package org.NooLab.structures.nlp;

import java.io.Serializable;
import java.util.ArrayList;


import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.strings.ArrUtilities;






public class WordSets implements Serializable{
	
	private static final long serialVersionUID = -8804859318258160613L;

	ArrayList<WordSet> items = new ArrayList<WordSet>();
	
	// ========================================================================
	public WordSets(){
		
	}
	// ========================================================================
	
	
	public void removeMatchingSet(int redundancies) {
		// 
		if (redundancies==9){
			clearPerfectMatches();
		}
		if (redundancies==1){
			clearCompleteInclusionsMatches();
		}
	}

	private void clearCompleteInclusionsMatches() {
		// TODO Auto-generated method stub
		
	}


	private void clearPerfectMatches() {
		// 
		WordSet ws_i,ws_k;
		
		for (int k=0;k<items.size();k++){
			
			ws_k = items.get(k) ;
			
			int i=items.size()-1;
			while (i>=k+1){
				
				ws_i = items.get(i) ;
				
				if (ws_k.isEqual(ws_i)){
					items.remove(i);
				}
				
				i--;
			}
			
		} // i ->
		
	}
	// ------------------------------------------------------------------------

	public int size(){
		return items.size();
	}
	public void clear(){
		items.clear();
	}
	public void add( WordSet ws){
		items.add(ws) ;
	}
	
	public void addAll( ArrayList<WordSet> inItems) {

		for (int i=0;i<inItems.size();i++){
			items.add( inItems.get(i)) ;
		}
	}

	public WordSet get(int index){
		WordSet ws=null;
		
		if ((index>=0) && (index<items.size())){
			ws = items.get(index) ;
		}
		return ws;
	}
	
	
	public ArrayList<WordSet> getItems() {
		return items;
	}

	public void setItems(ArrayList<WordSet> items) {
		this.items = items;
	}


	/**
	 * 
	 * @param resultSet
	 * @param mode 1=only labels as ; separated lists
	 */
	public void publishToResults( NLPresultSetIntf resultSet, int mode) {
		// 
		ArrayList<String> list, wsLabels = new ArrayList<String> ();
		String labels;
		
		resultSet.setWordSets( this );
		
		for (int i=0;i<this.items.size();i++){
		
			 list = items.get(i).getLabels();      
			 labels = ArrUtilities.arr2Text(list, "; ");
			 wsLabels.add(labels) ;
		} // i->
		
		resultSet.setWordsetLabels(wsLabels) ;
	}


	public ArrayList<String> getLabels() {
		String sep;
		ArrayList<String> labels = new ArrayList<String>();
		
		for (int i=0;i<items.size();i++){
			WordSet ws = items.get(i);
			sep=" " ;
			for (int k=0;k<ws.size();k++){
				if (k==ws.size()-1){
					sep="; " ;
				}
				labels.add( ws.getWord(k).getLabel()+sep );
			}
		}
		return null;
	}


	public boolean contains(WordSet cwset) {
		boolean rB=false;
		
		WordSet ws;
		
		for (int i=0;i<items.size();i++){
			
			ws = items.get(i);
			
			if (ws.isEqual(cwset)){
				rB=true;
				break;
			}
			
		}// i-> 
		
		return rB;
	}


	public void makeSetEntriesUnique() {

		WordSet ws;

		for (int i=0;i<items.size();i++){
			
			ws = items.get(i);
			ws.makeEntriesUnique();
			
		}// i-> 
		
	}


	public void collateSmallSets(int smallness, int maxCollationLen) {
		// 
		int n;
		WordSet ws;
		ArrayList<WordSet> smallSets   = new ArrayList<WordSet>(); 
		ArrayList<Integer> smallSetPos = new ArrayList<Integer>();

		if (items.size()<=1){
			return;
		}
		boolean done = false;
		int zz=0;
		while ((zz<items.size()) && (done==false)){

			smallSets.clear();
			smallSetPos.clear() ;
			
			
			for (int i = 0; i < items.size(); i++) {
				ws = items.get(i);
				n = ws.getWords().size();
				if (n <= smallness) {
					smallSets.add(ws);
					smallSetPos.add(i);
				}
			}// i->

			
			int sz = 1, sum;
			int[] sip = new int[maxCollationLen - 1];
		
			zz++;
			done = true;
			sum = 0;
			
			int k=0 ;
			for (int i=0;i<sip.length;i++){ sip[i]=-1;}
			
			for (int i=0;i<smallSets.size();i++){
				if (smallSets.get(i).size() <= sz){
					sip[k] = smallSetPos.get(i);
					k++;
					sum = sum + smallSets.get(i).size(); 
				}
				if (sum>=smallness+1){
					break;
				}
			}// i->

			if (k<=0){
				continue;
			}
			
			if (k>1){
				done=false;
				for (int i=1;i<sip.length;i++){
					if (sip[i]<0){
						continue;
					}
					items.get(sip[0]).getWords().addAll( items.get( sip[i]).getWords());
				}
				for (int i=sip.length-1;i>0;i--){
					if (sip[i]<0){
						continue;
					}
					items.remove(sip[i]);
				}
				
			}else{
				if (k==1){

					k=-1;
					for (int i=0;i<sip.length;i++){
						if (sip[i]<0){
							continue;
						}
						// the smallest set, except the current
						k = smallestSet(sip[i]);
						items.get(k).getWords().addAll( items.get( sip[i]).getWords());

					}// i-> sips
					done=false ;
					
					for (int i=sip.length-1;i>=0;i--){
						if (sip[i]<0){
							continue;
						}
						if (i!=k){
							items.remove(sip[i]);
						}
					}
	
				}
			}
			
			
			sz++;
			if (sz>maxCollationLen){
				done=true;
				break;
			}
		} // ? ->
		
		n=0;
	}
	
	
	private int smallestSet(int exceptPos) {
		
		int p=-1;
		int sz=99;
		
		for (int j=0;j<items.size();j++){
			int d = items.get(j).size();
			if ((j!=exceptPos) && (d<sz)){
				sz=d; p=j;
			}
		}
		return p;
	}


	public void disposeSmallSetsOf(String[] disposedPoS) {
		// 
		
		WordSet ws_i,ws_k;
		int n;
		boolean hb; 
		
		for (int k=0;k<items.size();k++){
			
			ws_k = items.get(k) ;
			n = ws_k.size();
			
			if (n<=2){
				for (int w=ws_k.size()-1;w>=0;w--){
					
					String synt = ws_k.getWord(w).PosTag ; 
					hb=false;
					for (int d=0;d<disposedPoS.length;d++){
						if (synt.contains(disposedPoS[d])){
							hb = true;
							break;
						}
					}
					if (hb){
						ws_k.getWords().remove(w) ;
					}
				}
			}
		
		}// -> k
		
	}

	
	
}
